package com.dffl.es.esstudy.service.impl;

import com.alibaba.fastjson.JSON;
import com.dffl.es.esstudy.convert.EsConverter;
import com.dffl.es.esstudy.dao.TPriceMapper;
import com.dffl.es.esstudy.dao.TSkuMapper;
import com.dffl.es.esstudy.dao.TSpuMapper;
import com.dffl.es.esstudy.document.EsPrice;
import com.dffl.es.esstudy.document.EsSku;
import com.dffl.es.esstudy.model.*;
import com.dffl.es.esstudy.repository.EsSkuRepository;
import com.dffl.es.esstudy.service.EsSkuService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * elasticsearch 搜索引擎 service实现
 */
@Service
public class EsSkuServiceImpl extends BaseSearchServiceImpl<EsSku> implements EsSkuService {
    private Logger log = LoggerFactory.getLogger(getClass());
    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;
    @Resource
    private EsSkuRepository esSkuRepository;
    @Resource
    private TSkuMapper tSkuMapper;
    @Resource
    private TPriceMapper priceMapper;
    @Resource
    private TSpuMapper tSpuMapper;

    @Override
    public int importAll() {
        int count = tSkuMapper.countByExample(null);
        int page = 0;
        int limit = 100;
        do {
            PageHelper.startPage(page, limit, "id asc");
            List<TSku> tSkuPageInfo = tSkuMapper.select(new TSku());
            PageInfo<TSku> pageList = new PageInfo<TSku>(tSkuPageInfo);
            List<Long> skuIds = tSkuPageInfo.stream().map(TSku::getId).collect(Collectors.toList());
            List<Long> spuIds = tSkuPageInfo.stream().map(TSku::getSpuId).collect(Collectors.toList());
            TPriceExample tPriceExample = new TPriceExample();
            tPriceExample.createCriteria().andSkuIdIn(skuIds);
            List<TPrice> tPrices = priceMapper.selectByExample(tPriceExample);


            TSpuExample tSpuExample = new TSpuExample();
            tSpuExample.createCriteria().andIdIn(spuIds);
            List<TSpu> tSpus = tSpuMapper.selectByExample(tSpuExample);
            Map<Long,List<TSpu>> spuMap = new HashMap<>();
            if (!CollectionUtils.isEmpty(tSpus)){
                spuMap =  tSpus.stream().collect(Collectors.groupingBy(TSpu::getId));
            }

            Map<Long, List<TPrice>> priceMap = new HashMap<>();
            if (!CollectionUtils.isEmpty(tPrices)){
                priceMap = tPrices.stream().collect(Collectors.groupingBy(TPrice::getSkuId));
            }
            Map<Long, List<TPrice>> finalPriceMap = priceMap;
            Map<Long, List<TSpu>> finalSpuMap = spuMap;
            List<EsSku> esSkus = pageList.getList().stream().map(e -> {
                EsSku esSku = EsConverter.INSTANCE.tSkuToEsSku(e);
                List<TPrice> prices = finalPriceMap.get(esSku.getId());
                if (!CollectionUtils.isEmpty(prices)){
                    List<EsPrice> esPrices = EsConverter.INSTANCE.tpriceToEsPrice(prices);
                    esSku.setPriceList(esPrices);
                }
                List<TSpu> spus = finalSpuMap.get(esSku.getSpuId());
                if (!CollectionUtils.isEmpty(spus)){
                    esSku.setSpu(EsConverter.INSTANCE.tSpuToEsSpu(spus.get(0)));
                }
                return esSku;
            }).collect(Collectors.toList());
            esSkuRepository.saveAll(esSkus);
            page++;
            log.info("【保存索引】：{}",JSON.toJSONString(esSkus));

        } while (page * limit <= count);
        return count;
    }

    @Override
    public void save(EsSku... esSkus) {
        elasticsearchTemplate.putMapping(EsSku.class);
        if(esSkus.length > 0){
            /*Arrays.asList(productDocuments).parallelStream()
                    .map(productDocumentRepository::save)
                    .forEach(productDocument -> log.info("【保存数据】：{}", JSON.toJSONString(productDocument)));*/
            log.info("【保存索引】：{}",JSON.toJSONString(esSkuRepository.saveAll(Arrays.asList(esSkus))));
        }
    }

    @Override
    public void delete(Long id) {
        esSkuRepository.deleteById(id);
    }

    @Override
    public void deleteAll() {
        esSkuRepository.deleteAll();
    }

    @Override
    public EsSku getById(Long id) {
        return esSkuRepository.findById(id).get();
    }

    @Override
    public List<EsSku> getAll() {
        List<EsSku> list = new ArrayList<>();
        esSkuRepository.findAll().forEach(list::add);
        return list;
    }

}
